/*
 * @Description: enter your description
 * @Autor: ˧ZR˧
 * @Date: 2023-09-21 21:11:31
 * @LastEditors: 帅ZR帅
 * @LastEditTime: 2023-11-28 17:17:35
 */
/*
 * @Description: enter your description
 * @Autor: ˧ZR˧
 * @Date: 2023-09-21 21:11:31
 * @LastEditors: ˧ZR˧
 * @LastEditTime: 2023-10-10 03:56:41
 */
#include "TAU1202.h"
#include <stdio.h>
#include <stdlib.h>
#include <HardwareSerial.h>
#include "queue.h"
#include <string.h>
#include "math.h"
#include "algorithm"
#include "cstdio"
#include "Bluetooth.h"
#include "OLED.h"
#include <U8g2lib.h>
#include "RFID.h"
#include "Esp_task_wdt.h"
#include "OLED.h"
HardwareSerial UART_GPS(2);
QueueHandle_t TAU1202_QUEUE;
SemaphoreHandle_t GPS_RECEIVE;
//**************************************GPSģ��**************************************************//
int MCU_GPS = 47;       // GPS  ��Դʹ�� �ߵ�ƽ��Ч(���)
int MCU_GPS_PRTRG = 48; // GPS �����ź� ��������
int U2TXD = 6;          // ����2TX
int U2RXD = 7;          // ����2RX
//**************************************GPSģ��**************************************************//
char str[250];
char *newValue;
char UART_DATA_GPS_PER;  // ����ÿ�ν��յ�������
char UART_DATA_GPS[500]; // ���ڽ�������
int len = 0;
int invalid_data_num = 0; // ��Ч���ݴ���
uint8_t UART_DATA_GPS_NUM = 0;
uint16_t UART_DATA_GPS_DATA[20];
uint8_t UART_DATA_GPS_DATA_NUM = 0;

uint8_t RMC_OPEN[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X05, 0X01, 0X00, 0X1A};
uint8_t GGA_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X00, 0X00, 0XFA, 0X0F};
uint8_t GLL_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X01, 0X00, 0XFB, 0X11};
uint8_t GSA_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X02, 0X00, 0XFC, 0X13};
uint8_t GRS_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X03, 0X00, 0XFD, 0X15};
uint8_t GSV_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X04, 0X00, 0XFE, 0X17};
uint8_t RMC_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X05, 0X00, 0XFF, 0X19};
uint8_t VTG_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X06, 0X00, 0X00, 0X1B};
uint8_t ZDA_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X07, 0X00, 0X01, 0X1D};
uint8_t GST_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X08, 0X00, 0X02, 0X1F};
uint8_t TXT_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X40, 0X00, 0X3A, 0X8F};
uint8_t ANT_CLOSE[11] = {0XF1, 0XD9, 0X06, 0X01, 0X03, 0X00, 0XF0, 0X20, 0X00, 0X1A, 0X4F};

enum TAU1202_DATA_TYPE
{
    RMC = 1,
};

struct TAU1202_DATA RMC_DATA;

void TAU1202_COMMAND(uint8_t *command)
{
    for (uint8_t i = 0; i < 12; i++)
    {
        UART_GPS.write(command[i]);
        esp_task_wdt_reset();
    }
}

void TAU1202_Data_Analysis(void)
{
    int i = 0;
    uint8_t gps_reveive_flag = 0;
    if (invalid_data_num < 5)
    {
        vTaskDelay(1 / portTICK_PERIOD_MS);
        do
        {
            gps_reveive_flag = 0;
            vTaskDelay(1 / portTICK_PERIOD_MS);
            if (pdPASS == xQueueReceive(TAU1202_QUEUE, (void *)&UART_DATA_GPS_PER, 0))
            {
                gps_reveive_flag = 1;
                vTaskDelay(1 / portTICK_PERIOD_MS);

                if (UART_DATA_GPS_PER == '$')
                {
                    RMC_DATA.data_num = 0;
                    memset(UART_DATA_GPS, 0, sizeof(UART_DATA_GPS));
                    memset(&RMC_DATA, 0, sizeof(RMC_DATA));
                    i = 0;
                    UART_DATA_GPS[i] = UART_DATA_GPS_PER;
                }
                else
                {
                    UART_DATA_GPS[++i] = UART_DATA_GPS_PER;
                }
                if (UART_DATA_GPS_PER == ',')
                {

                    // char *newValue = "123";
                    // pCharacteristic->setValue(newValue);
                    // pCharacteristic->notify();

                    RMC_DATA.data_num++;
                    char sbit_data[20] = {0};
                    uint16_t date = 0, mouth = 0, year = 0;
                    switch (RMC_DATA.data_num)
                    {
                    case 1: // ��ͷ
                        if (strcmp(UART_DATA_GPS, "$GNRMC,") == 0)
                        {
                            invalid_data_num = 0;
                            RMC_DATA.tital = RMC;
                            // Serial.print("$GNRMC\n");
                            // newValue = "$GNRMC";
                            // pCharacteristic->setValue(newValue);
                            // pCharacteristic->notify();
                            // u8g2.drawUTF8(30, 60, "GNRMC");
                            // u8g2.sendBuffer();
                            len = i;
                        }
                        else
                        {
                            RMC_DATA.tital = -1;
                            invalid_data_num++;
                        }
                        break;
                    case 2: // ʱ��
                        for (int j = len + 1; j < i; j++)
                        {
                            sbit_data[j - len - 1] = UART_DATA_GPS[j];
                        }
                        RMC_DATA.world_time = atof(sbit_data);
                        RMC_DATA.beijing_time = RMC_DATA.world_time + 80000.0f;
                        if (RMC_DATA.beijing_time > 240000)
                        {
                            RMC_DATA.beijing_time = RMC_DATA.beijing_time - 240000;
                        }
                        // sprintf(str, "%.2f", RMC_DATA.beijing_time);
                        // newValue = str;
                        // pCharacteristic->setValue(newValue);
                        // pCharacteristic->notify();
                        len = i;
                        break;
                    case 3: // ��λ״̬
                        for (int j = len + 1; j < i; j++)
                        {
                            if (UART_DATA_GPS[j] == 'A')
                            {
                                RMC_DATA.location_stauts = 1;
                                // newValue = "GPS_OK";
                                // pCharacteristic->setValue(newValue);
                                // pCharacteristic->notify();
                            }
                        }
                        len = i;
                        break;
                    case 4: // γ��
                        for (int j = len + 1; j < i; j++)
                        {
                            sbit_data[j - len - 1] = UART_DATA_GPS[j];
                        }
                        RMC_DATA.latitude = atof(sbit_data);
                        // sprintf(str, "latitude:%.7f", RMC_DATA.latitude);
                        // newValue = str;
                        // pCharacteristic->setValue(newValue);
                        // pCharacteristic->notify();
                        len = i;
                        break;
                    case 5: // �ϱ�γ
                        for (int j = len + 1; j < i; j++)
                        {
                            if (UART_DATA_GPS[j] == 'N')
                            {
                                RMC_DATA.latitude_dir = 1;
                            }
                            else if (UART_DATA_GPS[j] == 'S')
                            {
                                RMC_DATA.latitude_dir = 2;
                            }
                            else
                            {
                                RMC_DATA.latitude_dir = -1;
                            }
                        }
                        // Serial.print("latitude_dir:");
                        // Serial.print(RMC_DATA.latitude_dir);
                        // Serial.print("\n");
                        len = i;
                        break;
                    case 6: // ����
                        for (int j = len + 1; j < i; j++)
                        {
                            sbit_data[j - len - 1] = UART_DATA_GPS[j];
                        }
                        RMC_DATA.longitude = atof(sbit_data);
                        // sprintf(str, "longitude:%.7f", RMC_DATA.longitude);
                        // newValue = str;
                        // pCharacteristic->setValue(newValue);
                        // pCharacteristic->notify();
                        len = i;
                        break;
                    case 7: // ������
                        for (int j = len + 1; j < i; j++)
                        {
                            if (UART_DATA_GPS[j] == 'E')
                            {
                                RMC_DATA.longitude_dir = 1;
                            }
                            else if (UART_DATA_GPS[j] == 'W')
                            {
                                RMC_DATA.longitude_dir = 2;
                            }
                            else
                            {
                                RMC_DATA.longitude_dir = -1;
                            }
                        }
                        // Serial.print("longitude_dir:");
                        // Serial.print(RMC_DATA.longitude_dir);
                        // Serial.print("\n");
                        len = i;
                        break;
                    case 8: // �����ٶ�
                        for (int j = len + 1; j < i; j++)
                        {
                            sbit_data[j - len - 1] = UART_DATA_GPS[j];
                        }
                        RMC_DATA.ground_speed = atof(sbit_data);
                        // Serial.print("ground_speed:");
                        // Serial.print(RMC_DATA.ground_speed);
                        // Serial.print("\n");
                        len = i;
                        break;
                    case 9: // �����
                        for (int j = len + 1; j < i; j++)
                        {
                            sbit_data[j - len - 1] = UART_DATA_GPS[j];
                        }
                        RMC_DATA.ground_yaw = atof(sbit_data);
                        // Serial.print("ground_yaw:");
                        // Serial.print(RMC_DATA.ground_yaw);
                        // Serial.print("\n");
                        len = i;
                        break;
                    case 10: // ����
                        for (int j = len + 1; j < i; j++)
                        {
                            sbit_data[j - len - 1] = UART_DATA_GPS[j];
                        }
                        RMC_DATA.date = atol(sbit_data);
                        date = RMC_DATA.date / 10000;
                        mouth = (RMC_DATA.date - date * 10000) / 100;
                        year = (RMC_DATA.date - date * 10000 - mouth * 100);
                        RMC_DATA.date = year * 10000 + mouth * 100 + date;
                        // Serial.print("date:");
                        // Serial.print(RMC_DATA.date);
                        // Serial.print("\n");

                        len = i;
                        break;
                    default:
                        break;
                    }
                }
            }
        } while (UART_DATA_GPS_PER != '\n' && invalid_data_num < 5 && gps_reveive_flag);
    }
    else if (invalid_data_num >= 5) // 3S�� ����Ч����(RMC) ���³�ʼGPS
    {

        // // Serial.print("ERR\n");

        TAU1202_COMMAND(GGA_CLOSE);
        TAU1202_COMMAND(GLL_CLOSE);
        TAU1202_COMMAND(GSA_CLOSE);
        TAU1202_COMMAND(GRS_CLOSE);
        TAU1202_COMMAND(GSV_CLOSE);
        TAU1202_COMMAND(VTG_CLOSE);
        TAU1202_COMMAND(ZDA_CLOSE);
        TAU1202_COMMAND(GST_CLOSE);
        TAU1202_COMMAND(TXT_CLOSE);
        TAU1202_COMMAND(ANT_CLOSE);
        TAU1202_COMMAND(RMC_OPEN);

        char *newValue = "ERR_star\n";
        pCharacteristic->setValue(newValue);
        pCharacteristic->notify();
        invalid_data_num = 0;
    }
}

void TAU1202_READ(void)
{
    uint64_t receive_num = 0;
    if (UART_GPS.available())
    {
        char reveive_data[1];
        reveive_data[0] = UART_GPS.read();
        xQueueSend(TAU1202_QUEUE, (void *)&reveive_data, 0);
        receive_num++;
        if (reveive_data[0] == '\n')
        {
            receive_num = 0;
            xSemaphoreGive(GPS_RECEIVE);
        }
        // printf("GPS\n");
        vTaskDelay(1);
    }
    else if (pdTRUE == xSemaphoreTake(GPS_RECEIVE, 1000))
    {
        vTaskDelay(10);
        TAU1202_Data_Analysis();
        // printf("GPS231\n");
        // pCharacteristic->setValue(newValue);
        // pCharacteristic->notify();
    }
    // else
    // {
    //     vTaskDelay(10);
    // }
    //
}

void TAU1202_Init(void)
{ pinMode(MCU_GPS, OUTPUT);
 pinMode(MCU_GPS_PRTRG, OUTPUT);
       // ��ʼ��GPS��Դ����
    digitalWrite(MCU_GPS_PRTRG, HIGH); // GPS�ϵ�
    digitalWrite(MCU_GPS, HIGH); // GPS�ϵ�
    TAU1202_QUEUE = xQueueCreate(100, sizeof(char));
    GPS_RECEIVE = xSemaphoreCreateBinary();
    UART_GPS.begin(115200, SERIAL_8N1, 7, 6);
}